#pragma once
#include<iostream>
#include<string>
#include<cstring>
#include<cerrno>
#include<unistd.h>
#include"Comm.hpp"

namespace nt_client
{
    class TcpClient
    {
        void Service()
        {
            char buff[1024];
            std::string who=_server_ip+"-"+std::to_string(_server_port);

            while(true)
            {
                std::string msg;
                std::cout<<"Please Enter# ";
                std::getline(std::cin,msg);

                //发送信息给服务端
                write(_sock,msg.c_str(),msg.size());

                //接受来自服务器的信息
                ssize_t n=read(_sock,buff,sizeof(buff)-1);
                if(n>0)
                {
                    //正常通信
                    buff[n]='\0';
                    std::cout<<"Clint get: "<<buff<<"from "<<who<<std::endl;
                }
                else if(n==0)
                {
                    //读到文件末尾（服务器关闭）
                    std::cout<<"Server "<<who<<" quit!"<<std::endl;
                    close(_sock);
                    break;
                }
                else
                {
                    //读取异常
                    std::cerr<<"Read Fail"<<strerror(errno)<<std::endl;
                    close(_sock);
                    break;
                }
                
            }
        }

        
    public:
        TcpClient(const std::string& ip,const uint16_t port)
        :_server_port(port),_server_ip(ip)
        {

        }

        ~TcpClient()
        {

        }

        void InitClient()
        {
            //创建套接字(绑定服务端的)
            _sock=socket(AF_INET,SOCK_STREAM,0);
            if(_sock==-1)
            {
                perror("Create socket Fail");
                exit(SOCKET_ERR);
            }
            std::cout<<"Create socket succsee "<<_sock<<std::endl;
        }

        void StartClient()
        {
            struct sockaddr_in server;
            socklen_t len=sizeof(server);
            memset(&server,0,len);
            server.sin_family=AF_INET;
            server.sin_port=htons(_server_port);
            inet_aton(_server_ip.c_str(),&server.sin_addr);

            //尝试重连五次
            int n=5;
            while(n)
            {
                int ret=connect(_sock,(const struct sockaddr*)&server,len);

                if(ret==0)
                {
                    //连接成功，可以跳出循环
                    break;
                }

                std::cerr<<"网络异常，正在进行重连。。。剩余连接次数："<<--n<<std::endl;
                sleep(1);
            }

            if(n==0)
            {
                std::cerr<<"连接失败"<<strerror(errno)<<std::endl;
                close(_sock);
                exit(CONNECT_ERR);
            }

            std::cout<<"连接成功！"<<std::endl;

            Service();
        }
        
        

    private:
        int _sock;
        uint16_t _server_port;
        std::string _server_ip;
    };
}